# coding=utf-8
import paramiko,os,sys,datetime,time,re,select
from time import sleep

class SSHServer:
    # 通过IP, 用户名，密码，超时时间初始化一个远程Linux主机
    def __init__(self, ip, username, password, port, timeout=30):
        self.ip = ip
        self.username = username
        self.password = password
        self.port = port
        self.timeout = timeout
        # transport和chanel
        self.t = ''
        self.chan = ''
        # 链接失败的重试次数
        self.try_times = 3

    def connect(self):
        while True:
            # 连接过程中可能会抛出异常，比如网络不通、链接超时
            try:
                self.t = paramiko.Transport(sock=(self.ip, self.port))
                self.t.connect(username=self.username, password=self.password)
                self.chan = self.t.open_session()
                self.chan.settimeout(self.timeout)
                self.chan.get_pty()
                self.chan.invoke_shell()
                # 如果没有抛出异常说明连接成功，直接返回
                print u'连接%s:%s成功' % (self.ip,self.port)
                # 接收到的网络数据解码为str
                print self.chan.recv(65535).decode('utf-8')
                return
                # 这里不对可能的异常如socket.error, socket.timeout细化，直接一网打尽
            except Exception, e1:
                if self.try_times != 0:
                    print u'连接%s:%s失败，进行重试' % (self.ip,self.port)
                    self.try_times -= 1
                else:
                    print u'重试3次失败，结束程序'
                    exit(1)
                    # 断开连接


    def close(self):
        self.chan.close()
        self.t.close()
        print u'链接已断开'

    # 发送要执行的命令
    def send(self, cmd):
        readlist, writelist, errlist = select.select([self.chan, cmd, ], [], [])
        # 如果是用户输入命令了,sys.stdin发生变化
        if sys.stdin in readlist:
            # 获取输入的内容
            input_cmd = sys.stdin.read(1)
            # 将命令发送给服务器
        channel.sendall(input_cmd)

        # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到
        if self.chan in readlist:
            # 获取结果
            result = self.chan.recv(1024)
            # 断开连接后退出
            if len(result) == 0:
                print("\r\n**** EOF **** \r\n")
                #break
            # 输出到屏幕
            sys.stdout.write(result.decode())
            sys.stdout.flush()

    def sftp_upload_file(self,remote_path,local_path,fileName):
        #判断文件是否存在
        try:
            sftp = paramiko.SFTPClient.from_transport(self.t)
            sftp.put(local_path+fileName, remote_path+fileName)
            print u'文件传输完毕'
        except Exception, e:
            print u'文件传输出错'

    def checkPathExists(self,path):
        sftp = paramiko.SFTPClient.from_transport(self.t)
        try:
            sftp.stat(path)
            return True
        except IOError:
            return False

    def checkPathIsEmpty(self,path):
        stfp = paramiko.SFTPClient.from_transport(self.t)
        if len(stfp.listdir(path))==0:
            return True
        else:
            return False

class InstallMysqlTools:
    def __init__(self,server,installType,installPath):
        self.server = server
        self.installType = installType
        self.installPath = installPath

    def uncompress(self,uploadPath,fileName):
        if server.checkPathExists(self.installPath) and server.checkPathIsEmpty(self.installPath):
            # 执行解压命令
            print u'开始解压'
            try:
                server.send('tar -xzvf ' + uploadPath+fileName + ' -C ' + self.installPath + ' --strip-components 1')
            except Exception,e:
                print str(e)
            #print u'解压完毕'
        elif not server.checkPathExists(self.installPath):
            server.send('mkdir ' + self.installPath)
            print u'解压目录不存在。已创建解压目录'
            print u'开始解压'
            server.send('tar -xzvf ' + uploadPath+fileName + ' -C ' + self.installPath + ' --strip-components 1')
        else:
            print u'解压目录不为空。'
            sys.exit(0)



if __name__ == '__main__':
    localPath='/Users/liujiaqi/Downloads/'
    uploadPath = '/opt/soft/'
    installPath = '/opt/app/mysql_3307/'
    fileName = 'Percona-Server-5.6.36-rel82.0-Linux.x86_64.ssl101.tar.gz'
    server = SSHServer('192.168.1.104','root','123456',22)
    installer = InstallMysqlTools(server,u'binary',installPath)
    server.connect()
    #传输压缩包
    #server.sftp_upload_file(uploadPath,localPath,fileName)
    #解压安装包
    #installer.uncompress(uploadPath,fileName)
    server.send('ls\r')
    server.close()
